home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / toolmanager / source / prefs / imagewindow.c < prev    next >
C/C++ Source or Header  |  1993-05-15  |  14KB  |  509 lines

  1. /*
  2.  * imagewindow.c  V2.1
  3.  *
  4.  * image edit window handling
  5.  *
  6.  * (c) 1990-1993 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerConf.h"
  10.  
  11. /* Image node */
  12. struct ImageNode {
  13.                   struct Node  in_Node;
  14.                   char        *in_File;
  15.                  };
  16.  
  17. /* Window data */
  18. static struct Gadget *gl;             /* Gadget list */
  19. static struct Window *w;              /* Window */
  20. static void *aw;                      /* AppWindow pointer */
  21. static UWORD ww,wh;                   /* Window size */
  22. static struct ImageNode *CurrentNode;
  23. static char *DirName=NULL;
  24. static struct Requester DummyReq;
  25.  
  26. /* Gadget data */
  27. #define GAD_NAME_STR 0
  28. #define GAD_FILE_BUT 1
  29. #define GAD_FILE_TXT 2
  30. #define GAD_FILE_STR 3
  31. #define GAD_OK       4
  32. #define GAD_CANCEL   5
  33. #define GADGETS      6
  34. static struct GadgetData gdata[GADGETS];
  35.  
  36. /* Gadget tags */
  37. static struct TagItem nametags[]={GTST_String,   NULL,
  38.                                   GTST_MaxChars, SGBUFLEN,
  39.                                   TAG_DONE};
  40.  
  41. static struct TagItem filetags[]={GTST_String,   NULL,
  42.                                   GTST_MaxChars, SGBUFLEN,
  43.                                   TAG_DONE};
  44.  
  45. /* Gadget vanilla key data */
  46. #define KEY_NAME   0
  47. #define KEY_FILE   1
  48. #define KEY_OK     2
  49. #define KEY_CANCEL 3
  50. static char KeyArray[KEY_CANCEL+1];
  51.  
  52. /* Init image edit window */
  53. void InitImageEditWindow(UWORD left, UWORD fheight)
  54. {
  55.  ULONG tmp,tmp2,maxw1,maxw2;
  56.  ULONG strheight=fheight+2;
  57.  struct GadgetData *gd;
  58.  
  59.  /* Init strings */
  60.  gdata[GAD_OK].name    =AppStrings[MSG_WINDOW_OK_GAD];
  61.  gdata[GAD_CANCEL].name=AppStrings[MSG_WINDOW_CANCEL_GAD];
  62.  
  63.  /* Calculate maximum label width for string gadgets */
  64.  maxw1=TextLength(&TmpRastPort,AppStrings[MSG_WINDOW_NAME_GAD],
  65.                   strlen(AppStrings[MSG_WINDOW_NAME_GAD]));
  66.  tmp=TextLength(&TmpRastPort,AppStrings[MSG_IMAGEWIN_FILE_GAD],
  67.                 strlen(AppStrings[MSG_IMAGEWIN_FILE_GAD]))+REQBUTTONWIDTH;
  68.  if (tmp > maxw1) maxw1=tmp;
  69.  maxw1+=INTERWIDTH;
  70.  
  71.  /* Calculate minimal string gadgets width */
  72.  ww=TextLength(&TmpRastPort,
  73.                AppStrings[MSG_IMAGEWIN_NEWNAME],
  74.                strlen(AppStrings[MSG_IMAGEWIN_NEWNAME])
  75.               ) + maxw1 + 3*INTERWIDTH;
  76.  
  77.  /* Calculate button gadgets width */
  78.  gd=&gdata[GAD_OK];
  79.  maxw2=TextLength(&TmpRastPort,gd->name,strlen(gd->name));
  80.  gd++;
  81.  if ((tmp=TextLength(&TmpRastPort,gd->name,strlen(gd->name))) > maxw2)
  82.   maxw2=tmp;
  83.  maxw2+=2*INTERWIDTH;
  84.  if ((tmp=2*(maxw2+INTERWIDTH)) > ww) ww=tmp;
  85.  
  86.  /* window height */
  87.  wh=3*fheight+4*INTERHEIGHT+4;
  88.  
  89.  /* Init gadgets */
  90.  gd=gdata;
  91.  tmp=WindowTop+INTERHEIGHT;
  92.  tmp2=ww-maxw1-INTERWIDTH;
  93.  maxw1+=left;
  94.  
  95.  /* Name string gadget */
  96.  gd->name=AppStrings[MSG_WINDOW_NAME_GAD];
  97.  gd->type=STRING_KIND;
  98.  gd->flags=PLACETEXT_LEFT;
  99.  gd->tags=nametags;
  100.  gd->left=maxw1;
  101.  gd->top=tmp;
  102.  gd->width=tmp2;
  103.  gd->height=strheight;
  104.  tmp+=strheight+INTERHEIGHT;
  105.  
  106.  /* File name button gadget */
  107.  gd++;
  108.  gd->type=GENERIC_KIND;
  109.  gd->flags=0;
  110.  gd->left=maxw1-REQBUTTONWIDTH;
  111.  gd->top=tmp;
  112.  gd->width=REQBUTTONWIDTH;
  113.  gd->height=strheight;
  114.  
  115.  /* File name text gadget */
  116.  gd++;
  117.  gd->name=AppStrings[MSG_IMAGEWIN_FILE_GAD];
  118.  gd->type=TEXT_KIND;
  119.  gd->flags=PLACETEXT_LEFT;
  120.  gd->left=maxw1-REQBUTTONWIDTH;
  121.  gd->top=tmp+strheight/2;
  122.  gd->width=0;
  123.  gd->height=0;
  124.  
  125.  /* File name string gadget */
  126.  gd++;
  127.  gd->type=STRING_KIND;
  128.  gd->tags=filetags;
  129.  gd->left=maxw1;
  130.  gd->top=tmp;
  131.  gd->width=tmp2;
  132.  gd->height=strheight;
  133.  tmp+=strheight+INTERHEIGHT;
  134.  
  135.  /* OK button gadget */
  136.  gd++;
  137.  gd->type=BUTTON_KIND;
  138.  gd->flags=PLACETEXT_IN;
  139.  gd->left=left;
  140.  gd->top=tmp;
  141.  gd->width=maxw2;
  142.  gd->height=fheight;
  143.  
  144.  /* Cancel button gadget */
  145.  gd++;
  146.  gd->type=BUTTON_KIND;
  147.  gd->flags=PLACETEXT_IN;
  148.  gd->left=ww-maxw2-INTERWIDTH+left;
  149.  gd->top=tmp;
  150.  gd->width=maxw2;
  151.  gd->height=fheight;
  152.  
  153.  /* Init vanilla key array */
  154.  KeyArray[KEY_NAME]  =FindVanillaKey(gdata[GAD_NAME_STR].name);
  155.  KeyArray[KEY_FILE]  =FindVanillaKey(gdata[GAD_FILE_TXT].name);
  156.  KeyArray[KEY_OK]    =FindVanillaKey(gdata[GAD_OK].name);
  157.  KeyArray[KEY_CANCEL]=FindVanillaKey(gdata[GAD_CANCEL].name);
  158.  
  159.  /* Init dummy requester structure */
  160.  InitRequester(&DummyReq);
  161. }
  162.  
  163. /* Free image node */
  164. void FreeImageNode(struct Node *node)
  165. {
  166.  struct ImageNode *in=(struct ImageNode *) node;
  167.  char *s;
  168.  
  169.  if (s=in->in_Node.ln_Name) free(s);
  170.  if (s=in->in_File) free(s);
  171.  
  172.  /* Free node */
  173.  FreeMem(in,sizeof(struct ImageNode));
  174. }
  175.  
  176. /* Copy image node */
  177. struct Node *CopyImageNode(struct Node *node)
  178. {
  179.  struct ImageNode *in,*orignode=(struct ImageNode *) node;
  180.  
  181.  /* Alloc memory for image node */
  182.  if (in=AllocMem(sizeof(struct ImageNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  183.  
  184.   /* Got an old node? */
  185.   if (orignode) {
  186.    /* Yes, copy it */
  187.    if ((!orignode->in_Node.ln_Name || (in->in_Node.ln_Name=
  188.                                   strdup(orignode->in_Node.ln_Name))) &&
  189.        (!orignode->in_File || (in->in_File=strdup(orignode->in_File))))
  190.     return(in);
  191.   } else
  192.    /* No, set defaults */
  193.    if ((in->in_Node.ln_Name=strdup(AppStrings[MSG_IMAGEWIN_NEWNAME])) &&
  194.        (!DirName || (in->in_File=strdup(DirName))))
  195.     /* Return pointer to new node */
  196.     return(in);
  197.  
  198.   FreeImageNode((struct Node *) in);
  199.  }
  200.  /* Call failed */
  201.  return(NULL);
  202. }
  203.  
  204. /* Create image node from WBArg */
  205. struct Node *CreateImageNode(char *name, struct WBArg *wa)
  206. {
  207.  struct ImageNode *in;
  208.  
  209.  /* Alloc memory for image node */
  210.  if (in=AllocMem(sizeof(struct ImageNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  211.   char *filebuf;
  212.  
  213.   /* Init node */
  214.   if ((in->in_Node.ln_Name=strdup(name)) &&
  215.       (filebuf=malloc(4096))) {
  216.  
  217.    /* Create & copy icon file name */
  218.    if (NameFromLock(wa->wa_Lock,filebuf,4096) &&
  219.        AddPart(filebuf,wa->wa_Name,4096) &&
  220.        (in->in_File=strdup(filebuf))) {
  221.     /* All OK. */
  222.     free(filebuf);
  223.     return(in);
  224.    }
  225.    free(filebuf);
  226.   }
  227.   FreeImageNode((struct Node *) in);
  228.  }
  229.  /* Call failed */
  230.  return(NULL);
  231. }
  232.  
  233. /* Activate gadget and save pointer to it */
  234. static void MyActivateGadget(ULONG num)
  235. {
  236.  ActivateGadget(gdata[num].gadget,w,NULL);
  237. }
  238.  
  239. /* Open image edit window */
  240. BOOL OpenImageEditWindow(struct Node *node, struct Window *parent)
  241. {
  242.  /* Copy node */
  243.  if (CurrentNode=(struct ImageNode *) CopyImageNode(node)) {
  244.   /* Set tags */
  245.   nametags[0].ti_Data=(ULONG) CurrentNode->in_Node.ln_Name;
  246.   filetags[0].ti_Data=(ULONG) CurrentNode->in_File;
  247.  
  248.   /* Create gadgets */
  249.   if (gl=CreateGadgetList(gdata,GADGETS)) {
  250.    /* Open window */
  251.    if (w=OpenWindowTags(NULL,WA_Left,        parent->LeftEdge,
  252.                              WA_Top,         parent->TopEdge+WindowTop,
  253.                              WA_InnerWidth,  ww,
  254.                              WA_InnerHeight, wh,
  255.                              WA_AutoAdjust,  TRUE,
  256.                              WA_Title,       AppStrings[MSG_IMAGEWIN_TITLE],
  257.                              WA_PubScreen,   PublicScreen,
  258.                              WA_Flags,       WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  259.                                              WFLG_DEPTHGADGET|WFLG_RMBTRAP|
  260.                                              WFLG_ACTIVATE,
  261.                              TAG_DONE)) {
  262.     /* Add as AppWindow */
  263.     aw=NULL;
  264.     if (WorkbenchBase && WBScreen)
  265.      /* This call fails if the Workbench is NOT running! */
  266.      aw=AddAppWindowA(0,0,w,AppMsgPort,NULL);
  267.  
  268.     /* Init requester button gadgets */
  269.     InitReqButtonGadget(gdata[GAD_FILE_BUT].gadget);
  270.  
  271.     /* Add gadgets to window */
  272.     AddGList(w,gl,(UWORD) -1,(UWORD) -1,NULL);
  273.     RefreshGList(gl,w,NULL,(UWORD) -1);
  274.     GT_RefreshWindow(w,NULL);
  275.  
  276.     /* Activate first gadget */
  277.     MyActivateGadget(GAD_NAME_STR);
  278.  
  279.     /* Set local variables */
  280.     w->UserPort=IDCMPPort;
  281.     w->UserData=(BYTE *) HandleImageEditWindowIDCMP;
  282.     ModifyIDCMP(w,IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|BUTTONIDCMP|
  283.                   STRINGIDCMP|IDCMP_VANILLAKEY);
  284.     CurrentWindow=w;
  285.     if (aw) HandleAppMsg=HandleImageEditWindowAppMsg;
  286.  
  287.     /* Set up file requester parameters */
  288.     FileReqParms.frp_Window=w;
  289.     FileReqParms.frp_Title=AppStrings[MSG_FILEREQ_TITLE_FILE];
  290.     FileReqParms.frp_OKText=AppStrings[MSG_FILEREQ_OK_GAD];
  291.     FileReqParms.frp_Flags1=FRF_DOPATTERNS;
  292.     FileReqParms.frp_Flags2=0;
  293.  
  294.     /* All OK. */
  295.     return(TRUE);
  296.    }
  297.    FreeGadgets(gl);
  298.   }
  299.   FreeImageNode((struct Node *) CurrentNode);
  300.  }
  301.  /* Call failed */
  302.  return(FALSE);
  303. }
  304.  
  305. /* Close image edit window */
  306. static void CloseImageEditWindow(void)
  307. {
  308.  /* Free resources */
  309.  RemoveGList(w,gl,(UWORD) -1);
  310.  if (aw) {
  311.   HandleAppMsg=HandleMainWindowAppMsg;
  312.   RemoveAppWindow(aw);
  313.  }
  314.  CloseWindowSafely(w);
  315.  FreeGadgets(gl);
  316. }
  317.  
  318. /* Handle application messages */
  319. void HandleImageEditWindowAppMsg(struct AppMessage *msg)
  320. {
  321.  struct WBArg *wa;
  322.  
  323.  /* Get first argument */
  324.  if (wa=msg->am_ArgList) {
  325.   char *filebuf;
  326.  
  327.   /* Allocate memory for name buffer */
  328.   if (filebuf=malloc(4096)) {
  329.    /* Build full file name */
  330.    if (NameFromLock(wa->wa_Lock,filebuf,4096) &&
  331.        AddPart(filebuf,wa->wa_Name,4096)) {
  332.     /* Set new gadget values */
  333.     GT_SetGadgetAttrs(gdata[GAD_NAME_STR].gadget,w,NULL,
  334.                       GTST_String,wa->wa_Name,TAG_DONE);
  335.     GT_SetGadgetAttrs(gdata[GAD_FILE_STR].gadget,w,NULL,
  336.                       GTST_String,filebuf,TAG_DONE);
  337.    }
  338.    free(filebuf);
  339.   }
  340.  }
  341. }
  342.  
  343. /* File gadget function */
  344. static void FileGadgetFunc(void)
  345. {
  346.  char *file;
  347.  struct Gadget *g=gdata[GAD_FILE_STR].gadget;
  348.  
  349.  /* Set file requester parameters */
  350.  FileReqParms.frp_OldFile=((struct StringInfo *) g->SpecialInfo)->Buffer;
  351.  
  352.  /* Open file requester */
  353.  if (file=OpenFileRequester(&DummyReq)) {
  354.   char *path;
  355.  
  356.   /* Set new file string */
  357.   GT_SetGadgetAttrs(g,w,NULL,GTST_String,file,TAG_DONE);
  358.  
  359.   /* Get new path */
  360.   path=FilePart(file);
  361.   if (path!=file) {
  362.    /* Free old path */
  363.    if (DirName) free(DirName);
  364.  
  365.    /* Set new path */
  366.    DirName=file;
  367.    *path='\0';
  368.   }
  369.  
  370.   /* Activate string gadget */
  371.   MyActivateGadget(GAD_FILE_STR);
  372.  }
  373. }
  374.  
  375. /* OK gadget function */
  376. static struct Node *OKGadgetFunc(void)
  377. {
  378.  struct Node *rc;
  379.  char *s;
  380.  
  381.  /* Free old strings */
  382.  if (s=CurrentNode->in_Node.ln_Name) free(s);
  383.  CurrentNode->in_Node.ln_Name=NULL;
  384.  if (s=CurrentNode->in_File) free(s);
  385.  CurrentNode->in_File=NULL;
  386.  
  387.  /* Duplicate new strings */
  388.  if (((CurrentNode->in_Node.ln_Name=
  389.         DuplicateBuffer(gdata[GAD_NAME_STR].gadget)) != (char *) -1) &&
  390.      ((CurrentNode->in_File=
  391.         DuplicateBuffer(gdata[GAD_FILE_STR].gadget)) != (char *) -1)) {
  392.   char *s=CurrentNode->in_File;
  393.   ULONG len=strlen(s);
  394.  
  395.   /* Strip trailing ".info" */
  396.   if ((len>=5) && !stricmp(s+len-5,".info")) s[len-5]='\0';
  397.   rc=(struct Node *) CurrentNode;
  398.  } else {
  399.   /* Couldn't copy strings */
  400.   rc=(struct Node *) -1;
  401.   FreeImageNode((struct Node *) CurrentNode);
  402.  }
  403.  return(rc);
  404. }
  405.  
  406. /* Handle image edit window IDCMP events */
  407. void *HandleImageEditWindowIDCMP(struct IntuiMessage *msg)
  408. {
  409.  struct Node *NewNode=NULL;
  410.  
  411.  /* Which IDCMP class? */
  412.  switch (msg->Class) {
  413.   case IDCMP_CLOSEWINDOW:   NewNode=(struct Node *) -1;
  414.                             FreeImageNode((struct Node *) CurrentNode);
  415.                             break;
  416.   case IDCMP_REFRESHWINDOW: GT_BeginRefresh(w);
  417.                             GT_EndRefresh(w,TRUE);
  418.                             break;
  419.   case IDCMP_GADGETUP:
  420.    switch (((struct Gadget *) msg->IAddress)->GadgetID) {
  421.     case GAD_FILE_BUT: FileGadgetFunc();
  422.                        break;
  423.     case GAD_OK:       NewNode=OKGadgetFunc();
  424.                        break;
  425.     case GAD_CANCEL:   NewNode=(struct Node *) -1;
  426.                        FreeImageNode((struct Node *) CurrentNode);
  427.                        break;
  428.    }
  429.    break;
  430.   case IDCMP_VANILLAKEY:
  431.    switch (MatchVanillaKey(msg->Code,KeyArray)) {
  432.     case KEY_NAME:   MyActivateGadget(GAD_NAME_STR);
  433.                      break;
  434.     case KEY_FILE:   FileGadgetFunc();
  435.                      break;
  436.     case KEY_OK:     NewNode=OKGadgetFunc();
  437.                      break;
  438.     case KEY_CANCEL: NewNode=(struct Node *) -1;
  439.                      FreeImageNode((struct Node *) CurrentNode);
  440.                      break;
  441.    }
  442.    break;
  443.  }
  444.  
  445.  /* Close window? */
  446.  if (NewNode) {
  447.   /* Yes. But first reply message!!! */
  448.   GT_ReplyIMsg(msg);
  449.   CloseImageEditWindow();
  450.  }
  451.  
  452.  return(NewNode);
  453. }
  454.  
  455. /* Read TMIM IFF chunk into Image node */
  456. struct Node *ReadImageNode(UBYTE *buf)
  457. {
  458.  struct ImageNode *in;
  459.  
  460.  /* Allocate memory for node */
  461.  if (in=AllocMem(sizeof(struct ImageNode),MEMF_PUBLIC|MEMF_CLEAR)) {
  462.   struct ImagePrefsObject *ipo=(struct ImagePrefsObject *) buf;
  463.   ULONG sbits=ipo->ipo_StringBits;
  464.   UBYTE *ptr=(UBYTE *) &ipo[1];
  465.  
  466.   if ((!(sbits & IMPO_NAME) || (in->in_Node.ln_Name=GetConfigStr(&ptr))) &&
  467.       (!(sbits & IMPO_FILE) || (in->in_File=GetConfigStr(&ptr))))
  468.    /* All OK. */
  469.    return(in);
  470.  
  471.   /* Call failed */
  472.   FreeImageNode((struct Node *) in);
  473.  }
  474.  return(NULL);
  475. }
  476.  
  477. /* Write Image node to TMIM IFF chunk */
  478. BOOL WriteImageNode(struct IFFHandle *iff, UBYTE *buf, struct Node *node)
  479. {
  480.  struct ImageNode *in=(struct ImageNode *) node;
  481.  struct ImagePrefsObject *ipo=(struct ImagePrefsObject *) buf;
  482.  ULONG sbits=0;
  483.  UBYTE *ptr=(UBYTE *) &ipo[1];
  484.  
  485.  /* Copy strings */
  486.  if (PutConfigStr(in->in_Node.ln_Name,&ptr)) sbits|=IMPO_NAME;
  487.  if (PutConfigStr(in->in_File,&ptr)) sbits|=IMPO_FILE;
  488.  
  489.  /* set string bits */
  490.  ipo->ipo_StringBits=sbits;
  491.  
  492.  /* calculate length */
  493.  sbits=ptr-buf;
  494.  
  495.  DEBUG_PRINTF("chunk size %ld\n",sbits);
  496.  
  497.  /* Open chunk */
  498.  if (PushChunk(iff,0,ID_TMIM,sbits)) return(FALSE);
  499.  
  500.  /* Write chunk */
  501.  if (WriteChunkBytes(iff,buf,sbits)!=sbits) return(FALSE);
  502.  
  503.  /* Close chunk */
  504.  if (PopChunk(iff)) return(FALSE);
  505.  
  506.  /* All OK. */
  507.  return(TRUE);
  508. }
  509.